home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / wmlib / menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-29  |  5.8 KB  |  257 lines

  1. /* menu.c - menu interface functions
  2.  * 
  3.  * WMlib - WindowMaker application programming interface
  4.  * 
  5.  * Copyright (C) 1997 Alfredo K. Kojima
  6.  *  
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *  
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *  
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27.  
  28. #include "WMaker.h"
  29. #include "app.h"
  30. #include "menu.h"
  31.  
  32.  
  33. WMMenu*
  34. WMMenuCreate(WMAppContext *app, char *title)
  35. {
  36.     wmMenu *menu;
  37.  
  38.     if (strlen(title)>255)
  39.       return NULL;
  40.  
  41.     menu = malloc(sizeof(wmMenu));
  42.     if (!menu)
  43.       return NULL;
  44.     
  45.     menu->appcontext = app;
  46.     menu->parent = NULL;
  47.     menu->title = title;
  48.     menu->entries = NULL;
  49.     menu->first = NULL;
  50.  
  51.     menu->realized = False;
  52.     menu->code = app->last_menu_tag++;
  53.     
  54.     menu->entryline = malloc(strlen(title)+32);
  55.     menu->entryline2 = malloc(32);
  56.     if (!menu->entryline || !menu->entryline2) {
  57.     if (menu->entryline)
  58.       free(menu->entryline);
  59.     free(menu);
  60.     return NULL;
  61.     }
  62.     sprintf(menu->entryline, "%i %i %s", wmBeginMenu, menu->code, title);
  63.     sprintf(menu->entryline2, "%i %i", wmEndMenu, menu->code);
  64.     return menu;
  65. }
  66.  
  67.  
  68. int
  69. WMMenuAddItem(WMMenu *menu, char *text, WMMenuAction action,
  70.           void *clientData, WMFreeFunction freedata, char *rtext)
  71. {
  72.     wmMenuEntry *entry;
  73.  
  74.     /* max size of right side text */
  75.     if (rtext && strlen(rtext)>4)
  76.       return -1;
  77.  
  78.     /* max size of menu text */
  79.     if (strlen(text)>255)
  80.       return -1;
  81.     
  82.     entry = malloc(sizeof(wmMenuEntry));
  83.     if (!entry)
  84.       return -1;
  85.     
  86.     entry->entryline = malloc(strlen(text)+100);
  87.     if (!entry->entryline) {
  88.     free(menu);
  89.     return -1;
  90.     }
  91.  
  92.     if (menu->entries)
  93.       entry->order = menu->entries->order + 1;
  94.     else {
  95.     entry->order = 0;
  96.     menu->first = entry;
  97.     }
  98.     entry->next = NULL;
  99.     entry->prev = menu->entries;
  100.     if (menu->entries)
  101.       menu->entries->next = entry;
  102.     menu->entries = entry;
  103.  
  104.     entry->menu = menu;
  105.     entry->text = text;
  106.     entry->shortcut = rtext;
  107.     entry->callback = action;
  108.     entry->clientData = clientData;
  109.     entry->free = freedata;
  110.     entry->tag = menu->appcontext->last_menu_tag++;
  111.     entry->cascade = NULL;
  112.     entry->enabled = True;
  113.  
  114.  
  115.     if (!rtext)
  116.       sprintf(entry->entryline, "%i %i %i %i %s", wmNormalItem,
  117.           menu->code, entry->tag, True, text);
  118.     else
  119.       sprintf(entry->entryline, "%i %i %i %i %s %s", wmDoubleItem,
  120.           menu->code, entry->tag, True, rtext, text);
  121.     return entry->tag;
  122. }
  123.  
  124.  
  125.  
  126. int
  127. WMMenuAddSubmenu(WMMenu *menu, char *text, WMMenu *submenu)
  128. {
  129.     wmMenuEntry *entry;
  130.  
  131.     /* max size of menu text */
  132.     if (strlen(text)>255)
  133.       return -1;
  134.     
  135.     entry = malloc(sizeof(wmMenuEntry));
  136.     if (!entry)
  137.       return -1;
  138.     
  139.     entry->entryline = malloc(strlen(text)+100);
  140.     if (!entry->entryline) {
  141.     free(menu);
  142.     return -1;
  143.     }
  144.  
  145.     if (menu->entries)
  146.       entry->order = menu->entries->order + 1;
  147.     else {
  148.     entry->order = 0;
  149.     menu->first = entry;
  150.     }
  151.     entry->next = NULL;
  152.     entry->prev = menu->entries;
  153.     if (menu->entries)
  154.       menu->entries->next = entry;
  155.     menu->entries = entry;
  156.     entry->menu = menu;
  157.     entry->text = text;
  158.     entry->shortcut = NULL;
  159.     entry->callback = NULL;
  160.     entry->clientData = NULL;
  161.     entry->tag = menu->appcontext->last_menu_tag++;
  162.     entry->cascade = submenu;
  163.     entry->enabled = True;
  164.  
  165.     sprintf(entry->entryline, "%i %i %i %i %i %s", wmSubmenuItem,
  166.         menu->code, entry->tag, True, submenu->code, text);
  167.     return entry->tag;    
  168. }
  169.  
  170.  
  171. static int
  172. countItems(WMMenu *menu)
  173. {
  174.     wmMenuEntry *entry = menu->first;
  175.     int c;
  176.  
  177.     c = 1;
  178.     while (entry) {
  179.     c++;
  180.     if (entry->cascade) {
  181.         c += countItems(entry->cascade);
  182.     }
  183.     entry = entry->next;
  184.     }
  185.     c++;
  186.     return c;
  187. }
  188.  
  189.  
  190. static void
  191. addItems(char **slist, int *index, WMMenu *menu)
  192. {
  193.     wmMenuEntry *entry = menu->first;
  194.     
  195.     slist[(*index)++] = menu->entryline;
  196.     while (entry) {
  197.     slist[(*index)++] = entry->entryline;
  198.     if (entry->cascade) {
  199.         addItems(slist, index, entry->cascade);
  200.     }
  201.     entry = entry->next;
  202.     }
  203.     slist[(*index)++] = menu->entryline2;
  204. }
  205.  
  206.  
  207. static Atom
  208. getatom(Display *dpy)
  209. {
  210.     static Atom atom=0;
  211.     
  212.     if (atom==0) {
  213.     atom = XInternAtom(dpy, WMMENU_PROPNAME, False);
  214.     }
  215.     return atom;
  216. }
  217.  
  218. int 
  219. WMRealizeMenus(WMAppContext *app)
  220. {
  221.     int i, count;
  222.     char **slist;
  223.     XTextProperty text_prop;
  224.  
  225.     if (!app->main_menu)
  226.       return False;
  227.     
  228.     /* first count how many menu items there are */
  229.     count = countItems(app->main_menu);
  230.     if (count==0)
  231.       return True;
  232.  
  233.     count++;
  234.     slist = malloc(count*sizeof(char*));
  235.     if (!slist) {
  236.     return False;
  237.     }
  238.  
  239.     slist[0] = "WMMenu 0";
  240.     i = 1;
  241.     addItems(slist, &i, app->main_menu);
  242.  
  243.     if (!XStringListToTextProperty(slist, i, &text_prop)) {
  244.     free(slist);
  245.     return False;
  246.     }
  247.     free(slist);
  248.     XSetTextProperty(app->dpy, app->main_window, &text_prop, 
  249.              getatom(app->dpy));
  250.  
  251.     XFree(text_prop.value);
  252.  
  253.     return True;
  254. }
  255.  
  256.  
  257.